//! Mock Appender 实现
//!
//! 提供测试用的 Appender 实现，支持：
//! - 事件捕获和验证
//! - 失败模拟
//! - 写入延迟模拟
//! - 线程安全操作

#![allow(dead_code)]

use log4r::{Appender, Level, Log4rError, LogEvent};
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
use std::sync::{Arc, Mutex};

/// 捕获的日志事件（兼容旧版）
#[derive(Debug, Clone)]
pub struct CapturedEvent {
    pub level: String,
    pub message: String,
    pub target: String,
    pub timestamp: String,
}

/// Mock Appender（旧版兼容）
#[derive(Debug, Clone, Default)]
pub struct MockAppender {
    events: Arc<Mutex<Vec<CapturedEvent>>>,
}

impl MockAppender {
    pub fn new() -> Self {
        Self {
            events: Arc::new(Mutex::new(Vec::new())),
        }
    }

    pub fn record(&self, level: &str, message: &str, target: &str) {
        if let Ok(mut events) = self.events.lock() {
            events.push(CapturedEvent {
                level: level.to_string(),
                message: message.to_string(),
                target: target.to_string(),
                timestamp: String::new(),
            });
        }
    }

    pub fn get_events(&self) -> Vec<CapturedEvent> {
        self.events.lock().map(|e| e.clone()).unwrap_or_default()
    }

    pub fn count_level(&self, level: &str) -> usize {
        self.get_events()
            .iter()
            .filter(|e| e.level.eq_ignore_ascii_case(level))
            .count()
    }

    pub fn contains_message(&self, message: &str) -> bool {
        self.get_events()
            .iter()
            .any(|e| e.message.contains(message))
    }

    pub fn clear(&self) {
        if let Ok(mut events) = self.events.lock() {
            events.clear();
        }
    }
}

/// TestAppender - 增强版测试 Appender
///
/// 实现 Appender trait，支持：
/// - 事件捕获和验证
/// - 失败模拟 (`with_failure`)
/// - 写入延迟模拟 (`with_delay`)
/// - flush/close 调用计数
#[derive(Debug)]
pub struct TestAppender {
    /// 捕获的事件列表
    events: Arc<Mutex<Vec<LogEvent>>>,
    /// 是否模拟写入失败
    fail_on_write: Arc<AtomicBool>,
    /// 写入延迟（毫秒）
    write_delay_ms: Arc<AtomicU64>,
    /// flush 调用次数
    flush_count: Arc<AtomicU64>,
    /// close 调用次数
    close_count: Arc<AtomicU64>,
}

impl TestAppender {
    /// 创建新的 TestAppender
    pub fn new() -> Self {
        Self {
            events: Arc::new(Mutex::new(Vec::new())),
            fail_on_write: Arc::new(AtomicBool::new(false)),
            write_delay_ms: Arc::new(AtomicU64::new(0)),
            flush_count: Arc::new(AtomicU64::new(0)),
            close_count: Arc::new(AtomicU64::new(0)),
        }
    }

    /// 配置写入失败模式
    ///
    /// # 示例
    /// ```ignore
    /// let appender = TestAppender::new().with_failure(true);
    /// assert!(appender.write(&event).is_err());
    /// ```
    pub fn with_failure(self, fail: bool) -> Self {
        self.fail_on_write.store(fail, Ordering::SeqCst);
        self
    }

    /// 配置写入延迟（毫秒）
    ///
    /// # 示例
    /// ```ignore
    /// let appender = TestAppender::new().with_delay(100);
    /// ```
    pub fn with_delay(self, delay_ms: u64) -> Self {
        self.write_delay_ms.store(delay_ms, Ordering::SeqCst);
        self
    }

    /// 设置失败模式（运行时）
    pub fn set_failure(&self, fail: bool) {
        self.fail_on_write.store(fail, Ordering::SeqCst);
    }

    /// 获取所有捕获的事件
    pub fn get_events(&self) -> Vec<LogEvent> {
        self.events.lock().map(|g| g.clone()).unwrap_or_default()
    }

    /// 获取事件数量
    pub fn count(&self) -> usize {
        self.events.lock().map(|g| g.len()).unwrap_or(0)
    }

    /// 清空所有事件
    pub fn clear(&self) {
        if let Ok(mut e) = self.events.lock() {
            e.clear();
        }
    }

    /// 检查是否包含指定消息
    pub fn contains_message(&self, msg: &str) -> bool {
        self.get_events().iter().any(|e| e.message.contains(msg))
    }

    /// 统计指定级别的事件数量
    pub fn count_level(&self, level: Level) -> usize {
        self.get_events()
            .iter()
            .filter(|e| e.level == level)
            .count()
    }

    /// 获取最后一个事件
    pub fn last_event(&self) -> Option<LogEvent> {
        self.get_events().last().cloned()
    }

    /// 获取 flush 调用次数
    pub fn flush_count(&self) -> u64 {
        self.flush_count.load(Ordering::SeqCst)
    }

    /// 获取 close 调用次数
    pub fn close_count(&self) -> u64 {
        self.close_count.load(Ordering::SeqCst)
    }

    /// 重置所有计数器和事件
    pub fn reset(&self) {
        self.clear();
        self.flush_count.store(0, Ordering::SeqCst);
        self.close_count.store(0, Ordering::SeqCst);
        self.fail_on_write.store(false, Ordering::SeqCst);
        self.write_delay_ms.store(0, Ordering::SeqCst);
    }
}

impl Clone for TestAppender {
    fn clone(&self) -> Self {
        Self {
            events: Arc::clone(&self.events),
            fail_on_write: Arc::clone(&self.fail_on_write),
            write_delay_ms: Arc::clone(&self.write_delay_ms),
            flush_count: Arc::clone(&self.flush_count),
            close_count: Arc::clone(&self.close_count),
        }
    }
}

impl Default for TestAppender {
    fn default() -> Self {
        Self::new()
    }
}

impl Appender for TestAppender {
    fn write(&self, event: &LogEvent) -> Result<(), Log4rError> {
        // 检查是否模拟失败
        if self.fail_on_write.load(Ordering::SeqCst) {
            return Err(Log4rError::AppenderError {
                name: "TestAppender".to_string(),
                cause: "模拟写入失败".to_string(),
            });
        }

        // 模拟写入延迟
        let delay = self.write_delay_ms.load(Ordering::SeqCst);
        if delay > 0 {
            std::thread::sleep(std::time::Duration::from_millis(delay));
        }

        // 写入事件
        self.events
            .lock()
            .map_err(|_| Log4rError::AppenderError {
                name: "TestAppender".to_string(),
                cause: "获取锁失败".to_string(),
            })?
            .push(event.clone());
        Ok(())
    }

    fn flush(&self) -> Result<(), Log4rError> {
        self.flush_count.fetch_add(1, Ordering::SeqCst);
        Ok(())
    }

    fn close(&self) -> Result<(), Log4rError> {
        self.close_count.fetch_add(1, Ordering::SeqCst);
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_appender_captures_events() {
        let appender = TestAppender::new();
        let event = LogEvent::new(Level::Info, "test", "message");
        appender.write(&event).unwrap();
        assert_eq!(appender.count(), 1);
    }

    #[test]
    fn test_appender_failure_mode() {
        let appender = TestAppender::new().with_failure(true);
        let event = LogEvent::new(Level::Info, "test", "message");
        assert!(appender.write(&event).is_err());
    }

    #[test]
    fn test_appender_counts() {
        let appender = TestAppender::new();
        appender.flush().unwrap();
        appender.flush().unwrap();
        appender.close().unwrap();
        assert_eq!(appender.flush_count(), 2);
        assert_eq!(appender.close_count(), 1);
    }
}
